package com.slice.upload.strategy.biz;

import com.slice.upload.base.IStrategy;
import com.slice.upload.base.UploadMode;
import com.slice.upload.strategy.BaseSliceUploadStrategy;
import com.slice.upload.strategy.FileUploadPayload;
import lombok.extern.slf4j.Slf4j;

import java.io.File;
import java.io.RandomAccessFile;
import java.util.Objects;

/**
 * @ClassName RandomAccessUploadStrategy
 * @Description RandomAccessFile 上传策略
 * @Author frinder
 * @Date 2021/1/27 15:15
 * @Verion 1.0
 */
@Slf4j
public class RandomAccessUploadStrategy extends BaseSliceUploadStrategy {

    @Override
    public void handle(FileUploadPayload payload, IStrategy strategy) {
        if (UploadMode.RANDOM.is(payload.getMode())) {
            try {
                // 写文件
                writeChunk(payload);
                // 设置响应结果
                setRespond(payload);
            } catch (Exception e) {
                log.error(e.getMessage(), e);
            }
        } else {
            // 执行下一个策略
            strategy.handle(payload, strategy);
        }
    }

    /**
     * 写入分片文件
     *
     * @param payload
     */
    private void writeChunk(FileUploadPayload payload) {
        File tmpFile = super.createTmpFile(payload);
        try (RandomAccessFile file = new RandomAccessFile(tmpFile, "rw")) {
            // 块大小，这个必须与前端设定的值一致
            long chunkSize = Objects.isNull(payload.getChunkFileSize()) ? defaultChunkSize : payload.getChunkFileSize();
            // 计算偏移量
            long offset = chunkSize * payload.getChunk();
            // 定位到该分片的偏移量
            file.seek(offset);
            // 写入该分片数据
            file.write(payload.getFile().getBytes());
        } catch (Exception e) {
            log.error(e.getMessage(), e);
        }
    }

}
